package impl

import (
	"context"
	"errors"
	"github.com/samber/lo"
	"github.com/sirupsen/logrus"
	"html/template"
	"monoblog/common/register"
	"monoblog/domain/dao"
	"monoblog/domain/dto"
	"monoblog/domain/model"
	"monoblog/domain/service"
	"time"
)

func init() {
	register.RegisterInstance[service.CategoryService]("CategoryService", func() service.CategoryService {
		return &CategoryServiceImpl{
			categoryRepository: dao.NewCategoryRepository(),
			articleRepository:  dao.NewArticleRepository(),
		} // 返回唯一实例
	})
}

type CategoryServiceImpl struct {
	categoryRepository *dao.CategoryRepository
	articleRepository  *dao.ArticleRepository
}

func (s *CategoryServiceImpl) Add(ctx context.Context, form dto.CategoryReqForm) (string, error) {
	category := &model.Category{
		Name:       form.Name,
		Seq:        form.Seq,
		Icon:       form.Icon,
		CreateTime: time.Now(),
	}
	//判断Name是否重复
	exists, _ := s.categoryRepository.ExistsByName("", form.Name)
	if exists {
		return "", errors.New("category name is duplicated")
	}

	err := s.categoryRepository.Add(category)
	if err != nil {
		logrus.Errorf("[aid: %s] Add category failed: %v", ctx.Value("aid"), err.Error())
		return "", err
	}
	logrus.Infof("[aid: %s] Add category success: %v", ctx.Value("aid"), category.ID)
	return category.ID, nil
}

func (s *CategoryServiceImpl) UpdateByID(ctx context.Context, id string, form dto.CategoryReqForm) error {
	//判断是否存在
	exists, _ := s.categoryRepository.ExistsByName(id, form.Name)
	if exists {
		return errors.New("category name is duplicated")
	}

	category := &model.Category{
		Name: form.Name,
		Seq:  form.Seq,
		Icon: form.Icon,
	}

	err := s.categoryRepository.UpdateByID(id, *category)
	return err
}

func (s *CategoryServiceImpl) DeleteByID(ctx context.Context, id string) error {
	//先判断category下面有没有文章，如果有的话，不能删除
	count, err := s.articleRepository.FindCountByCategoryID(id, false)
	if err != nil {
		logrus.Errorf("[aid: %s] findCountByCategoryID failed: %v", ctx.Value("aid"), err.Error())
		return err
	}
	if count > 0 {
		return errors.New("category has articles, can not be deleted")
	}

	err = s.categoryRepository.DeleteByID(id) //删除category
	return err
}

func (s *CategoryServiceImpl) FindByID(ctx context.Context, id string) (*model.Category, error) {
	category, err := s.categoryRepository.FindByID(id)
	if category != nil {
		category.RenderedIcon = template.HTML(category.Icon)
	}
	return category, err
}

func (s *CategoryServiceImpl) FindList(ctx context.Context) ([]*model.Category, error) {
	categories, _, err := s.categoryRepository.FindList()

	lo.ForEach(categories, func(it *model.Category, index int) {
		it.RenderedIcon = template.HTML(it.Icon)
	})
	return categories, err
}
